package com.lingjtx.gencode;

import java.sql.*;
import java.util.ArrayList;
import java.util.List;

public class DatabaseUtil {
    private final Connection connection;

    public DatabaseUtil(String url, String username, String password) throws SQLException {
        this.connection = DriverManager.getConnection(url, username, password);
    }

    /**
     * 获取数据库中的所有表名
     */
    public List<String> getTableNames() throws SQLException {
        List<String> tableNames = new ArrayList<>();
        DatabaseMetaData metaData = connection.getMetaData();
        // 获取当前连接的数据库名称（Catalog）
        String catalog = connection.getCatalog();

        // 获取当前连接的 Schema（通常与数据库名称相同）
        String schema = connection.getSchema();
        ResultSet rs = metaData.getTables(catalog, schema, "%", new String[]{"TABLE"});
        while (rs.next()) {
            tableNames.add(rs.getString("TABLE_NAME"));
        }
        return tableNames;
    }

    /**
     * 获取表的主键字段名
     */
    public String getPrimaryKey(String tableName) throws SQLException {
        DatabaseMetaData metaData = connection.getMetaData();

        // 获取当前连接的数据库名称（Catalog）
        String catalog = connection.getCatalog();

        // 获取当前连接的 Schema（通常与数据库名称相同）
        String schema = connection.getSchema();
        ResultSet rs = metaData.getPrimaryKeys(catalog, schema, tableName);
        String primaryKey = null;
        while (rs.next()) {
            primaryKey = rs.getString("COLUMN_NAME");
            // 假设只有一个主键（复合主键需要额外处理）
            break;
        }
        return primaryKey;
    }

    /**
     * 获取字段的注释
     */
    private String getColumnComment(String tableName, String columnName) throws SQLException {
        String comment = "";
        String sql = "SELECT COLUMN_COMMENT " +
                "FROM information_schema.COLUMNS " +
                "WHERE TABLE_SCHEMA = ? " +
                "  AND TABLE_NAME = ? " +
                "  AND COLUMN_NAME = ?";
        try (PreparedStatement stmt = connection.prepareStatement(sql)) {
            stmt.setString(1, connection.getCatalog()); // 当前数据库
            stmt.setString(2, tableName); // 表名
            stmt.setString(3, columnName); // 字段名
            ResultSet rs = stmt.executeQuery();
            if (rs.next()) {
                comment = rs.getString("COLUMN_COMMENT");
            }
        }
        return comment;
    }

    /**
     * 获取表的字段信息
     */
    public List<Column> getColumns(String tableName) throws SQLException {
        List<Column> columns = new ArrayList<>();
        String primaryKey = getPrimaryKey(tableName); // 获取主键字段名
        DatabaseMetaData metaData = connection.getMetaData();
        // 获取当前连接的数据库名称（Catalog）
        String catalog = connection.getCatalog();

        // 获取当前连接的 Schema（通常与数据库名称相同）
        String schema = connection.getSchema();
        ResultSet rs = metaData.getColumns(catalog, schema, tableName, null);
        while (rs.next()) {
            String columnName = rs.getString("COLUMN_NAME");
            String columnType = rs.getString("TYPE_NAME");
            String javaType = CommonUtils.mapToJavaType(columnType); // 映射到 Java 类型
            String comment = getColumnComment(tableName, columnName); // 获取字段注释
            boolean isPrimary = columnName.equals(primaryKey); // 判断是否为主键
            columns.add(new Column(columnName, javaType, toCamelCase(columnName), comment, isPrimary));
        }
        return columns;
    }

    /**
     * 关闭数据库连接
     */
    public void close() throws SQLException {
        if (connection != null) {
            connection.close();
        }
    }

    /**
     * 将数据库字段名转换为驼峰命名
     */
    private String toCamelCase(String columnName) {
        StringBuilder result = new StringBuilder();
        String[] parts = columnName.split("_");
        for (int i = 0; i < parts.length; i++) {
            if (i == 0) {
                result.append(parts[i]);
            } else {
                result.append(parts[i].substring(0, 1).toUpperCase()).append(parts[i].substring(1));
            }
        }
        return result.toString();
    }
}
